package com.core;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import com.core.interfaces.IMessageManager;
import com.google.protobuf.GeneratedMessage;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageLite;



/**
 * 消息体管理类
 * 通过配置或者程序注入的方式 根据 moduleid和actionid以及二进制协议可以得到对应的消息体
 * @author King
 *
 */
public class MessageManager implements IMessageManager
{
	
	private static final Logger log = Logger.getLogger(MessageManager.class);
	
	private Map<Class<? extends GeneratedMessage>, MessageLite> bodyMap = new HashMap<Class<? extends GeneratedMessage>, MessageLite>();
	
	private Map<Integer, Map<Integer, MessageLite>> messageMap = new HashMap<Integer, Map<Integer, MessageLite>>();
	
	@Override
	public MessageLite getBody(Class<? extends GeneratedMessage> msgCla,
			byte[] body) {
		if(msgCla==null)
			return null;
		if(body==null||body.length==0)
			return null;
		MessageLite lite = bodyMap.get(msgCla);
		if(lite==null)
		{
			try {
				Method method = msgCla.getMethod("getDefaultInstance");
				lite = (MessageLite)method.invoke(null, null);
			} catch (Exception e) {
				log.error(e);
				e.printStackTrace();
			}
			bodyMap.put(msgCla, lite);
		};
		try {
			return lite.newBuilderForType().mergeFrom(body).build();
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void addMessageCla(int modelId, int actionId,
			Class<? extends GeneratedMessage> msgCla) {
		try {
			Method method = msgCla.getMethod("getDefaultInstance");
			MessageLite lite = (MessageLite)method.invoke(null, null);
			Map<Integer, MessageLite> map = messageMap.get(modelId);
			if(map==null)
			{
				map = new HashMap<Integer, MessageLite>();
			}
			map.put(actionId, lite);
			messageMap.put(modelId, map);
		} catch (Throwable e) {
			log.error(e);
			e.printStackTrace();
		}
	}

	@Override
	public MessageLite getMessage(int modelId, int actionId, byte[] body) 
	{
		try {
			Map<Integer, MessageLite> map = messageMap.get(modelId);
			if(map==null)
				return null;
			MessageLite list = map.get(actionId);
			if(list==null)
				return null;
			return list.newBuilderForType().mergeFrom(body).build();
		} catch (InvalidProtocolBufferException e) {
			log.error(e);
			e.printStackTrace();
		}
		return null;
	}

	
	
	public MessageLite getMessage(int modelId, int actionId) 
	{
		Map<Integer, MessageLite> map = messageMap.get(modelId);
		if(map==null)
			return null;
		MessageLite list = map.get(actionId);
		return list;
	}
	
	
}
